/**
 * 81. 搜索旋转排序数组 II
 * https://leetcode-cn.com/problems/search-in-rotated-sorted-array-ii/
 */
public class Solutions_81 {
    public static void main(String[] args) {
//        int[] nums = {2, 5, 6, 0, 0, 1, 2};
//        int target = 0;  // output: true
//        int target = 3;  // output: false
//        int target = 5;  // output: true

        int[] nums = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1};
        int target = 2;  // output: true

//        int[] nums = {1, 1};
//        int target = 2;  // output: false

//        int[] nums = {1, 1, 1, 3};
//        int target = 4;  // output: false

//        int[] nums = {1, 3, 1};
//        int target = 4;  // output: false

//        int[] nums = {3, 1, 2, 3, 3, 3, 3};
//        int target = 4;  // output: false

        boolean result = search(nums, target);
        System.out.println(result);
    }

    /**
     * 解题思路：二分查找
     */
    public static boolean search(int[] nums, int target) {
        int len = nums.length;
        int left = 0, right = len - 1;

        while (left <= right) {
            int mid = left + (right - left) / 2;
            if (nums[mid] == target) {
                return true;
            }
            if (nums[left] == nums[mid] && nums[right] == nums[mid]) {
                // 关键：去除重复元素
                left ++;
                right --;
            } else if (nums[mid] >= nums[left]) {
                // 左部分有序
                if (target >= nums[left] && target < nums[mid]) {
                    // target 可能位于左部分
                    right = mid - 1;
                } else {
                    // target 可能位于右部分
                    left = mid + 1;
                }
            } else if (nums[mid] <= nums[right]) {
                // 右部分有序
                if (target > nums[mid] && target <= nums[right]) {
                    // target 可能位于右部分
                    left = mid + 1;
                } else {
                    // target 可能位于左部分
                    right = mid - 1;
                }
            }
        }
        return false;
    }
}
